package io.gitee.zhangbinhub.admin.deploy.controller

import cn.dev33.satoken.annotation.SaCheckRole
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.cloud.annotation.AcpCloudDuplicateSubmission
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.deploy.bus.publish.DeployEventPublish
import io.gitee.zhangbinhub.admin.deploy.constant.DeployApi
import io.gitee.zhangbinhub.admin.deploy.entity.DeployTask
import io.gitee.zhangbinhub.admin.deploy.po.DeployTaskPo
import io.gitee.zhangbinhub.admin.deploy.po.DeployTaskQueryPo
import io.gitee.zhangbinhub.admin.deploy.service.DeployTaskService
import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.noear.solon.annotation.Body
import org.noear.solon.annotation.Controller
import org.noear.solon.annotation.Mapping
import org.noear.solon.annotation.Path
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.NotEmpty
import org.noear.solon.validation.annotation.NotNull
import org.noear.solon.validation.annotation.Valid
import org.noear.solon.validation.annotation.Validated

@Valid
@Controller
@Api("部署任务管理")
open class DeployTaskController(
    logAdapter: LogAdapter,
    private val deployTaskService: DeployTaskService,
    private val deployEventPublish: DeployEventPublish
) : BaseResourceServerController(logAdapter) {
    @ApiOperation("新建部署任务")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.PUT],
        value = DeployApi.basePath + DeployApi.task,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @AcpCloudDuplicateSubmission
    @Throws(WebException::class)
    fun add(@Body @Validated deployTaskPo: DeployTaskPo): DeployTask =
        deployTaskService.doCreate(deployTaskPo)

    @ApiOperation("删除指定的部署任务")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.DELETE],
        value = DeployApi.basePath + DeployApi.task,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun delete(
        @ApiParam(name = "id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @Body
        idList: MutableList<String>
    ): InfoVo = deployTaskService.doDelete(idList).let {
        InfoVo(message = "删除成功")
    }

    @ApiOperation("更新指定的部署任务")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.PATCH],
        value = DeployApi.basePath + DeployApi.task,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @AcpCloudDuplicateSubmission
    @Throws(WebException::class)
    fun update(@Body @Validated deployTaskPo: DeployTaskPo): DeployTask {
        if (CommonTools.isNullStr(deployTaskPo.id)) {
            throw WebException("ID不能为空")
        }
        return deployTaskService.doUpdate(deployTaskPo)
    }

    @ApiOperation("查询部署任务列表")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.POST],
        value = DeployApi.basePath + DeployApi.task,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun query(@Body @Validated deployTaskQueryPo: DeployTaskQueryPo): CustomerQueryPageVo<DeployTask> =
        deployTaskQueryPo.let {
            if (it.startTime != null) {
                it.startTime = longToDate(it.startTime!!).millis
            }
            if (it.endTime != null) {
                it.endTime = longToDate(it.endTime!!).millis
            }
            deployTaskService.doQuery(deployTaskQueryPo)
        }

    @ApiOperation("执行部署任务")
    @SaCheckRole(RoleCode.SUPER)
    @Mapping(
        method = [MethodType.POST],
        value = DeployApi.basePath + DeployApi.taskExecute + "/{id}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun execute(@Path(name = "id") id: String): InfoVo =
        deployTaskService.executeTask(id).let { deployTask ->
            deployEventPublish.doNotifyExecuteDeploy(deployTask.id).let {
                InfoVo(message = "请求成功，稍后将执行部署任务")
            }
        }
}